import {
  _decorator,
  Component,
  Node,
  Prefab,
  instantiate,
  SpriteFrame,
} from "cc";
import DataManager from "../Global/DataManager";
import { JoyStickManage } from "../UI/JoyStickManager";
import { ResourceManager } from "../Global/ResourceManager";
import { ActorManager } from "../Entity/Actor/ActorManager";
import { PrefabPathEnum, TexturePathEnum } from "../Enum";
import { EntityTypeEnum, InputTypeEnum } from "../Common";
import { BulletManager } from "../Entity/Bullet/BulletManager";
const { ccclass, property } = _decorator;

@ccclass("battleManager")
export class battleManager extends Component {
  private Stage: Node; // 舞台
  private UI: Node; // 摇杆、xxx等按钮
  private shouldUpdate = false; // 一个Flag
  onLoad() {
    // 获取节点
    DataManager.Instance.stage = this.Stage = this.node.getChildByName("Stage");
    // 获取节点
    this.UI = this.node.getChildByName("UI");
    // 把预制体之前的本体全部删掉
    this.Stage.destroyAllChildren();
    // 获取摇杆实例
    DataManager.Instance.jm = this.UI.getComponentInChildren(JoyStickManage);
  }
  start() {
    this.loadRes();
  }
  update(dt) {
    if (!this.shouldUpdate) return;
    this.render();
    this.tick(dt);
  }
  tick(dt) {
    this.tickActor(dt);
    DataManager.Instance.applyInput({
      type:InputTypeEnum.TimePast,dt
    })
  }
  render() {
    this.renderActor();
    this.renderBullet();
  }
  initMap() {
    const prefab = DataManager.Instance.prefabMap.get(EntityTypeEnum.Map);
    const map = instantiate(prefab);
    map.setParent(this.Stage);
  }
  // 这个函数是整理所有的预制体到一个 Map 里面
  async loadRes() {
    // 这个list实际意义是辅助记录要加载的所有资源，让下面的await Promise.all(list)检查等待
    const list = [];
    for (const type in PrefabPathEnum) {
      const p = ResourceManager.Instance.loadRes(
        PrefabPathEnum[type],
        Prefab
      ).then((Prefab) => {
        // 将资源加载好后放到一个Map里
        DataManager.Instance.prefabMap.set(type, Prefab);
      });
      list.push(p);
    }
    // 等待一切准备好，加载地图（下一行）
    await Promise.all(list);
    this.initMap();
    for (const type in TexturePathEnum) {
      const p = ResourceManager.Instance.loadDir(
        TexturePathEnum[type],
        SpriteFrame
      ).then((spriteFrame) => {
        DataManager.Instance.textureMap.set(type, spriteFrame);
      });
      list.push(p);
    }
    // 等待一切准备好，让声明周期update起作用（下一行）
    await Promise.all(list);
    this.shouldUpdate = true;
  }
  tickActor(dt) {
    for (const data of DataManager.Instance.state.actors) {
      const { id } = data;
      let am = DataManager.Instance.actorMap.get(id);
      if (am) am.tick(dt);
    }
  }
  async renderActor() {
    // 遍历所有玩家
    for (const data of DataManager.Instance.state.actors) {
      const { id, type } = data;
      let am = DataManager.Instance.actorMap.get(id);
      // 如果actorMap里没有这个玩家，就加载，并初始化，否则直接渲染
      if (!am) {
        const prefab = DataManager.Instance.prefabMap.get(type);
        if (typeof prefab == "object") {
          const actor = instantiate(prefab);
          actor.setParent(this.Stage);
          am = actor.addComponent(ActorManager);
          DataManager.Instance.actorMap.set(id, am);
          am.init(data);
        }
      } else {
        am.render(data);
      }
    }
  }
  renderBullet() {
    // 遍历所有子弹
    for (const data of DataManager.Instance.state.bullets) {
      const { id, type } = data;
      let bm = DataManager.Instance.bulletMap.get(id);
      if (!bm) {
        const prefab = DataManager.Instance.prefabMap.get(type);
        if (typeof prefab == "object") {
          const bullet = instantiate(prefab);
          bullet.setParent(this.Stage);
          bm = bullet.addComponent(BulletManager);
          DataManager.Instance.bulletMap.set(id, bm);
          bm.init(data);
        }
      } else {
        bm.render(data);
      }
    }
  }
}
